package yang.yu.sunny.domain;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.dayatang.domain.AbstractEntity;

import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 产品定价实体.记录
 * Created by yyang on 16/3/23.
 */
@Entity
@Table(name = "product_prices")
public class ProductPrice extends AbstractEntity implements Comparable<ProductPrice> {

    @ManyToOne
    private Product product;

    private double unitPrice;

    @Temporal(TemporalType.TIMESTAMP)
    private Date fromTime = new Date();

    protected ProductPrice() {
    }

    public ProductPrice(Product product, double unitPrice) {
        this(product, unitPrice, new Date());
    }

    public ProductPrice(Product product, double unitPrice, Date fromTime) {
        this.product = product;
        this.unitPrice = unitPrice;
        this.fromTime = fromTime;
    }

    public Product getProduct() {
        return product;
    }

    public double getUnitPrice() {
        return unitPrice;
    }

    public Date getFromTime() {
        return fromTime;
    }

    @Override
    public int compareTo(ProductPrice o) {
        return this.getFromTime().compareTo(o.getFromTime());
    }

    public static Optional<Double> getPriceOfProductAtTime(Product product, Date time) {
        List<ProductPrice> prices = getProductPricesOf(product);
        return prices.stream()
                .filter(it -> it.fromTime.before(time) || it.fromTime.equals(time))
                .findFirst()
                .map(ProductPrice::getUnitPrice);
    }

    private static List<ProductPrice> getProductPricesOf(Product product) {
        return getRepository().createCriteriaQuery(ProductPrice.class)
                    .eq("product", product)
                    .desc("fromTime")
                    .list();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (!(o instanceof ProductPrice)) return false;

        ProductPrice price = (ProductPrice) o;

        return new EqualsBuilder()
                .appendSuper(super.equals(o))
                .append(getProduct(), price.getProduct())
                .append(getFromTime(), price.getFromTime())
                .isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37)
                .appendSuper(super.hashCode())
                .append(getProduct())
                .append(getFromTime())
                .toHashCode();
    }
}
